//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension HealthLake {
    // MARK: Enums

    public enum CmkType: String, CustomStringConvertible, Codable, _SotoSendable {
        case awsOwnedKmsKey = "AWS_OWNED_KMS_KEY"
        case customerManagedKmsKey = "CUSTOMER_MANAGED_KMS_KEY"
        public var description: String { return self.rawValue }
    }

    public enum DatastoreStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case active = "ACTIVE"
        case creating = "CREATING"
        case deleted = "DELETED"
        case deleting = "DELETING"
        public var description: String { return self.rawValue }
    }

    public enum FHIRVersion: String, CustomStringConvertible, Codable, _SotoSendable {
        case r4 = "R4"
        public var description: String { return self.rawValue }
    }

    public enum JobStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case completed = "COMPLETED"
        case completedWithErrors = "COMPLETED_WITH_ERRORS"
        case failed = "FAILED"
        case inProgress = "IN_PROGRESS"
        case submitted = "SUBMITTED"
        public var description: String { return self.rawValue }
    }

    public enum PreloadDataType: String, CustomStringConvertible, Codable, _SotoSendable {
        case synthea = "SYNTHEA"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct CreateFHIRDatastoreRequest: AWSEncodableShape {
        /// Optional user provided token used for ensuring idempotency.
        public let clientToken: String?
        /// The user generated name for the Data Store.
        public let datastoreName: String?
        /// The FHIR version of the Data Store. The only supported version is R4.
        public let datastoreTypeVersion: FHIRVersion
        /// Optional parameter to preload data upon creation of the Data Store. Currently, the only supported preloaded data is synthetic data generated from Synthea.
        public let preloadDataConfig: PreloadDataConfig?
        ///  The server-side encryption key configuration for a customer provided encryption key specified for creating a Data Store.
        public let sseConfiguration: SseConfiguration?
        ///  Resource tags that are applied to a Data Store when it is created.
        public let tags: [Tag]?

        public init(clientToken: String? = CreateFHIRDatastoreRequest.idempotencyToken(), datastoreName: String? = nil, datastoreTypeVersion: FHIRVersion, preloadDataConfig: PreloadDataConfig? = nil, sseConfiguration: SseConfiguration? = nil, tags: [Tag]? = nil) {
            self.clientToken = clientToken
            self.datastoreName = datastoreName
            self.datastoreTypeVersion = datastoreTypeVersion
            self.preloadDataConfig = preloadDataConfig
            self.sseConfiguration = sseConfiguration
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.datastoreName, name: "datastoreName", parent: name, max: 256)
            try self.validate(self.datastoreName, name: "datastoreName", parent: name, min: 1)
            try self.validate(self.datastoreName, name: "datastoreName", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.sseConfiguration?.validate(name: "\(name).sseConfiguration")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case datastoreName = "DatastoreName"
            case datastoreTypeVersion = "DatastoreTypeVersion"
            case preloadDataConfig = "PreloadDataConfig"
            case sseConfiguration = "SseConfiguration"
            case tags = "Tags"
        }
    }

    public struct CreateFHIRDatastoreResponse: AWSDecodableShape {
        /// The datastore ARN is generated during the creation of the Data Store and can be found in the output from the initial Data Store creation call.
        public let datastoreArn: String
        /// The AWS endpoint for the created Data Store. For preview, only US-east-1 endpoints are supported.
        public let datastoreEndpoint: String
        /// The AWS-generated Data Store id. This id is in the output from the initial Data Store creation call.
        public let datastoreId: String
        /// The status of the FHIR Data Store. Possible statuses are ‘CREATING’, ‘ACTIVE’, ‘DELETING’, ‘DELETED’.
        public let datastoreStatus: DatastoreStatus

        public init(datastoreArn: String, datastoreEndpoint: String, datastoreId: String, datastoreStatus: DatastoreStatus) {
            self.datastoreArn = datastoreArn
            self.datastoreEndpoint = datastoreEndpoint
            self.datastoreId = datastoreId
            self.datastoreStatus = datastoreStatus
        }

        private enum CodingKeys: String, CodingKey {
            case datastoreArn = "DatastoreArn"
            case datastoreEndpoint = "DatastoreEndpoint"
            case datastoreId = "DatastoreId"
            case datastoreStatus = "DatastoreStatus"
        }
    }

    public struct DatastoreFilter: AWSEncodableShape {
        /// A filter that allows the user to set cutoff dates for records. All Data Stores created after the specified date will be included in the results.
        public let createdAfter: Date?
        /// A filter that allows the user to set cutoff dates for records. All Data Stores created before the specified date will be included in the results.
        public let createdBefore: Date?
        /// Allows the user to filter Data Store results by name.
        public let datastoreName: String?
        /// Allows the user to filter Data Store results by status.
        public let datastoreStatus: DatastoreStatus?

        public init(createdAfter: Date? = nil, createdBefore: Date? = nil, datastoreName: String? = nil, datastoreStatus: DatastoreStatus? = nil) {
            self.createdAfter = createdAfter
            self.createdBefore = createdBefore
            self.datastoreName = datastoreName
            self.datastoreStatus = datastoreStatus
        }

        public func validate(name: String) throws {
            try self.validate(self.datastoreName, name: "datastoreName", parent: name, max: 256)
            try self.validate(self.datastoreName, name: "datastoreName", parent: name, min: 1)
            try self.validate(self.datastoreName, name: "datastoreName", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case createdAfter = "CreatedAfter"
            case createdBefore = "CreatedBefore"
            case datastoreName = "DatastoreName"
            case datastoreStatus = "DatastoreStatus"
        }
    }

    public struct DatastoreProperties: AWSDecodableShape {
        /// The time that a Data Store was created.
        public let createdAt: Date?
        /// The Amazon Resource Name used in the creation of the Data Store.
        public let datastoreArn: String
        /// The AWS endpoint for the Data Store. Each Data Store will have it's own endpoint with Data Store ID in the endpoint URL.
        public let datastoreEndpoint: String
        /// The AWS-generated ID number for the Data Store.
        public let datastoreId: String
        /// The user-generated name for the Data Store.
        public let datastoreName: String?
        /// The status of the Data Store. Possible statuses are 'CREATING', 'ACTIVE', 'DELETING', or 'DELETED'.
        public let datastoreStatus: DatastoreStatus
        /// The FHIR version. Only R4 version data is supported.
        public let datastoreTypeVersion: FHIRVersion
        /// The preloaded data configuration for the Data Store. Only data preloaded from Synthea is supported.
        public let preloadDataConfig: PreloadDataConfig?
        ///  The server-side encryption key configuration for a customer provided encryption key (CMK).
        public let sseConfiguration: SseConfiguration?

        public init(createdAt: Date? = nil, datastoreArn: String, datastoreEndpoint: String, datastoreId: String, datastoreName: String? = nil, datastoreStatus: DatastoreStatus, datastoreTypeVersion: FHIRVersion, preloadDataConfig: PreloadDataConfig? = nil, sseConfiguration: SseConfiguration? = nil) {
            self.createdAt = createdAt
            self.datastoreArn = datastoreArn
            self.datastoreEndpoint = datastoreEndpoint
            self.datastoreId = datastoreId
            self.datastoreName = datastoreName
            self.datastoreStatus = datastoreStatus
            self.datastoreTypeVersion = datastoreTypeVersion
            self.preloadDataConfig = preloadDataConfig
            self.sseConfiguration = sseConfiguration
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "CreatedAt"
            case datastoreArn = "DatastoreArn"
            case datastoreEndpoint = "DatastoreEndpoint"
            case datastoreId = "DatastoreId"
            case datastoreName = "DatastoreName"
            case datastoreStatus = "DatastoreStatus"
            case datastoreTypeVersion = "DatastoreTypeVersion"
            case preloadDataConfig = "PreloadDataConfig"
            case sseConfiguration = "SseConfiguration"
        }
    }

    public struct DeleteFHIRDatastoreRequest: AWSEncodableShape {
        ///  The AWS-generated ID for the Data Store to be deleted.
        public let datastoreId: String?

        public init(datastoreId: String? = nil) {
            self.datastoreId = datastoreId
        }

        public func validate(name: String) throws {
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, max: 32)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, min: 1)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case datastoreId = "DatastoreId"
        }
    }

    public struct DeleteFHIRDatastoreResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) that gives Amazon HealthLake access permission.
        public let datastoreArn: String
        /// The AWS endpoint for the Data Store the user has requested to be deleted.
        public let datastoreEndpoint: String
        /// The AWS-generated ID for the Data Store to be deleted.
        public let datastoreId: String
        /// The status of the Data Store that the user has requested to be deleted.
        public let datastoreStatus: DatastoreStatus

        public init(datastoreArn: String, datastoreEndpoint: String, datastoreId: String, datastoreStatus: DatastoreStatus) {
            self.datastoreArn = datastoreArn
            self.datastoreEndpoint = datastoreEndpoint
            self.datastoreId = datastoreId
            self.datastoreStatus = datastoreStatus
        }

        private enum CodingKeys: String, CodingKey {
            case datastoreArn = "DatastoreArn"
            case datastoreEndpoint = "DatastoreEndpoint"
            case datastoreId = "DatastoreId"
            case datastoreStatus = "DatastoreStatus"
        }
    }

    public struct DescribeFHIRDatastoreRequest: AWSEncodableShape {
        /// The AWS-generated Data Store id. This is part of the ‘CreateFHIRDatastore’ output.
        public let datastoreId: String?

        public init(datastoreId: String? = nil) {
            self.datastoreId = datastoreId
        }

        public func validate(name: String) throws {
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, max: 32)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, min: 1)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case datastoreId = "DatastoreId"
        }
    }

    public struct DescribeFHIRDatastoreResponse: AWSDecodableShape {
        /// All properties associated with a Data Store, including the Data Store ID, Data Store ARN, Data Store name, Data Store status, created at, Data Store type version, and Data Store endpoint.
        public let datastoreProperties: DatastoreProperties

        public init(datastoreProperties: DatastoreProperties) {
            self.datastoreProperties = datastoreProperties
        }

        private enum CodingKeys: String, CodingKey {
            case datastoreProperties = "DatastoreProperties"
        }
    }

    public struct DescribeFHIRExportJobRequest: AWSEncodableShape {
        /// The AWS generated ID for the Data Store from which files are being exported from for an export job.
        public let datastoreId: String
        /// The AWS generated ID for an export job.
        public let jobId: String

        public init(datastoreId: String, jobId: String) {
            self.datastoreId = datastoreId
            self.jobId = jobId
        }

        public func validate(name: String) throws {
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, max: 32)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, min: 1)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.validate(self.jobId, name: "jobId", parent: name, max: 32)
            try self.validate(self.jobId, name: "jobId", parent: name, min: 1)
            try self.validate(self.jobId, name: "jobId", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case datastoreId = "DatastoreId"
            case jobId = "JobId"
        }
    }

    public struct DescribeFHIRExportJobResponse: AWSDecodableShape {
        /// Displays the properties of the export job, including the ID, Arn, Name, and the status of the job.
        public let exportJobProperties: ExportJobProperties

        public init(exportJobProperties: ExportJobProperties) {
            self.exportJobProperties = exportJobProperties
        }

        private enum CodingKeys: String, CodingKey {
            case exportJobProperties = "ExportJobProperties"
        }
    }

    public struct DescribeFHIRImportJobRequest: AWSEncodableShape {
        /// The AWS-generated ID of the Data Store.
        public let datastoreId: String
        /// The AWS-generated job ID.
        public let jobId: String

        public init(datastoreId: String, jobId: String) {
            self.datastoreId = datastoreId
            self.jobId = jobId
        }

        public func validate(name: String) throws {
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, max: 32)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, min: 1)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.validate(self.jobId, name: "jobId", parent: name, max: 32)
            try self.validate(self.jobId, name: "jobId", parent: name, min: 1)
            try self.validate(self.jobId, name: "jobId", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case datastoreId = "DatastoreId"
            case jobId = "JobId"
        }
    }

    public struct DescribeFHIRImportJobResponse: AWSDecodableShape {
        /// The properties of the Import job request, including the ID, ARN, name, and the status of the job.
        public let importJobProperties: ImportJobProperties

        public init(importJobProperties: ImportJobProperties) {
            self.importJobProperties = importJobProperties
        }

        private enum CodingKeys: String, CodingKey {
            case importJobProperties = "ImportJobProperties"
        }
    }

    public struct ExportJobProperties: AWSDecodableShape {
        /// The Amazon Resource Name used during the initiation of the job.
        public let dataAccessRoleArn: String?
        /// The AWS generated ID for the Data Store from which files are being exported for an export job.
        public let datastoreId: String
        /// The time an export job completed.
        public let endTime: Date?
        /// The AWS generated ID for an export job.
        public let jobId: String
        /// The user generated name for an export job.
        public let jobName: String?
        /// The status of a FHIR export job. Possible statuses are SUBMITTED, IN_PROGRESS, COMPLETED, or FAILED.
        public let jobStatus: JobStatus
        /// An explanation of any errors that may have occurred during the export job.
        public let message: String?
        /// The output data configuration that was supplied when the export job was created.
        public let outputDataConfig: OutputDataConfig
        /// The time an export job was initiated.
        public let submitTime: Date

        public init(dataAccessRoleArn: String? = nil, datastoreId: String, endTime: Date? = nil, jobId: String, jobName: String? = nil, jobStatus: JobStatus, message: String? = nil, outputDataConfig: OutputDataConfig, submitTime: Date) {
            self.dataAccessRoleArn = dataAccessRoleArn
            self.datastoreId = datastoreId
            self.endTime = endTime
            self.jobId = jobId
            self.jobName = jobName
            self.jobStatus = jobStatus
            self.message = message
            self.outputDataConfig = outputDataConfig
            self.submitTime = submitTime
        }

        private enum CodingKeys: String, CodingKey {
            case dataAccessRoleArn = "DataAccessRoleArn"
            case datastoreId = "DatastoreId"
            case endTime = "EndTime"
            case jobId = "JobId"
            case jobName = "JobName"
            case jobStatus = "JobStatus"
            case message = "Message"
            case outputDataConfig = "OutputDataConfig"
            case submitTime = "SubmitTime"
        }
    }

    public struct ImportJobProperties: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) that gives Amazon HealthLake access to your input data.
        public let dataAccessRoleArn: String?
        /// The datastore id used when the Import job was created.
        public let datastoreId: String
        /// The time that the Import job was completed.
        public let endTime: Date?
        /// The input data configuration that was supplied when the Import job was created.
        public let inputDataConfig: InputDataConfig
        /// The AWS-generated id number for the Import job.
        public let jobId: String
        /// The user-generated name for an Import job.
        public let jobName: String?
        public let jobOutputDataConfig: OutputDataConfig?
        /// The job status for an Import job. Possible statuses are SUBMITTED, IN_PROGRESS, COMPLETED, FAILED.
        public let jobStatus: JobStatus
        /// An explanation of any errors that may have occurred during the FHIR import job.
        public let message: String?
        /// The time that the Import job was submitted for processing.
        public let submitTime: Date

        public init(dataAccessRoleArn: String? = nil, datastoreId: String, endTime: Date? = nil, inputDataConfig: InputDataConfig, jobId: String, jobName: String? = nil, jobOutputDataConfig: OutputDataConfig? = nil, jobStatus: JobStatus, message: String? = nil, submitTime: Date) {
            self.dataAccessRoleArn = dataAccessRoleArn
            self.datastoreId = datastoreId
            self.endTime = endTime
            self.inputDataConfig = inputDataConfig
            self.jobId = jobId
            self.jobName = jobName
            self.jobOutputDataConfig = jobOutputDataConfig
            self.jobStatus = jobStatus
            self.message = message
            self.submitTime = submitTime
        }

        private enum CodingKeys: String, CodingKey {
            case dataAccessRoleArn = "DataAccessRoleArn"
            case datastoreId = "DatastoreId"
            case endTime = "EndTime"
            case inputDataConfig = "InputDataConfig"
            case jobId = "JobId"
            case jobName = "JobName"
            case jobOutputDataConfig = "JobOutputDataConfig"
            case jobStatus = "JobStatus"
            case message = "Message"
            case submitTime = "SubmitTime"
        }
    }

    public struct KmsEncryptionConfig: AWSEncodableShape & AWSDecodableShape {
        ///  The type of customer-managed-key(CMK) used for encyrption. The two types of supported CMKs are customer owned CMKs and AWS owned CMKs.
        public let cmkType: CmkType
        ///  The KMS encryption key id/alias used to encrypt the Data Store contents at rest.
        public let kmsKeyId: String?

        public init(cmkType: CmkType, kmsKeyId: String? = nil) {
            self.cmkType = cmkType
            self.kmsKeyId = kmsKeyId
        }

        public func validate(name: String) throws {
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, max: 400)
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, min: 1)
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, pattern: "^(arn:aws((-us-gov)|(-iso)|(-iso-b)|(-cn))?:kms:)?([a-z]{2}-[a-z]+(-[a-z]+)?-\\d:)?(\\d{12}:)?(((key/)?[a-zA-Z0-9-_]+)|(alias/[a-zA-Z0-9:/_-]+))$")
        }

        private enum CodingKeys: String, CodingKey {
            case cmkType = "CmkType"
            case kmsKeyId = "KmsKeyId"
        }
    }

    public struct ListFHIRDatastoresRequest: AWSEncodableShape {
        /// Lists all filters associated with a FHIR Data Store request.
        public let filter: DatastoreFilter?
        /// The maximum number of Data Stores returned in a single page of a ListFHIRDatastoresRequest call.
        public let maxResults: Int?
        /// Fetches the next page of Data Stores when results are paginated.
        public let nextToken: String?

        public init(filter: DatastoreFilter? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.filter = filter
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.filter?.validate(name: "\(name).filter")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 500)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^\\p{ASCII}{0,8192}$")
        }

        private enum CodingKeys: String, CodingKey {
            case filter = "Filter"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListFHIRDatastoresResponse: AWSDecodableShape {
        /// All properties associated with the listed Data Stores.
        public let datastorePropertiesList: [DatastoreProperties]
        /// Pagination token that can be used to retrieve the next page of results.
        public let nextToken: String?

        public init(datastorePropertiesList: [DatastoreProperties], nextToken: String? = nil) {
            self.datastorePropertiesList = datastorePropertiesList
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case datastorePropertiesList = "DatastorePropertiesList"
            case nextToken = "NextToken"
        }
    }

    public struct ListFHIRExportJobsRequest: AWSEncodableShape {
        ///  This parameter limits the response to the export job with the specified Data Store ID.
        public let datastoreId: String
        ///  This parameter limits the response to the export job with the specified job name.
        public let jobName: String?
        ///  This parameter limits the response to the export jobs with the specified job status.
        public let jobStatus: JobStatus?
        ///  This parameter limits the number of results returned for a ListFHIRExportJobs to a maximum quantity specified by the user.
        public let maxResults: Int?
        ///  A pagination token used to identify the next page of results to return for a ListFHIRExportJobs query.
        public let nextToken: String?
        ///  This parameter limits the response to FHIR export jobs submitted after a user specified date.
        public let submittedAfter: Date?
        ///  This parameter limits the response to FHIR export jobs submitted before a user specified date.
        public let submittedBefore: Date?

        public init(datastoreId: String, jobName: String? = nil, jobStatus: JobStatus? = nil, maxResults: Int? = nil, nextToken: String? = nil, submittedAfter: Date? = nil, submittedBefore: Date? = nil) {
            self.datastoreId = datastoreId
            self.jobName = jobName
            self.jobStatus = jobStatus
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.submittedAfter = submittedAfter
            self.submittedBefore = submittedBefore
        }

        public func validate(name: String) throws {
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, max: 32)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, min: 1)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.validate(self.jobName, name: "jobName", parent: name, max: 64)
            try self.validate(self.jobName, name: "jobName", parent: name, min: 1)
            try self.validate(self.jobName, name: "jobName", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 500)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^\\p{ASCII}{0,8192}$")
        }

        private enum CodingKeys: String, CodingKey {
            case datastoreId = "DatastoreId"
            case jobName = "JobName"
            case jobStatus = "JobStatus"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case submittedAfter = "SubmittedAfter"
            case submittedBefore = "SubmittedBefore"
        }
    }

    public struct ListFHIRExportJobsResponse: AWSDecodableShape {
        ///  The properties of listed FHIR export jobs, including the ID, ARN, name, and the status of the job.
        public let exportJobPropertiesList: [ExportJobProperties]
        ///  A pagination token used to identify the next page of results to return for a ListFHIRExportJobs query.
        public let nextToken: String?

        public init(exportJobPropertiesList: [ExportJobProperties], nextToken: String? = nil) {
            self.exportJobPropertiesList = exportJobPropertiesList
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case exportJobPropertiesList = "ExportJobPropertiesList"
            case nextToken = "NextToken"
        }
    }

    public struct ListFHIRImportJobsRequest: AWSEncodableShape {
        ///  This parameter limits the response to the import job with the specified Data Store ID.
        public let datastoreId: String
        ///  This parameter limits the response to the import job with the specified job name.
        public let jobName: String?
        ///  This parameter limits the response to the import job with the specified job status.
        public let jobStatus: JobStatus?
        ///  This parameter limits the number of results returned for a ListFHIRImportJobs to a maximum quantity specified by the user.
        public let maxResults: Int?
        ///  A pagination token used to identify the next page of results to return for a ListFHIRImportJobs query.
        public let nextToken: String?
        ///  This parameter limits the response to FHIR import jobs submitted after a user specified date.
        public let submittedAfter: Date?
        ///  This parameter limits the response to FHIR import jobs submitted before a user specified date.
        public let submittedBefore: Date?

        public init(datastoreId: String, jobName: String? = nil, jobStatus: JobStatus? = nil, maxResults: Int? = nil, nextToken: String? = nil, submittedAfter: Date? = nil, submittedBefore: Date? = nil) {
            self.datastoreId = datastoreId
            self.jobName = jobName
            self.jobStatus = jobStatus
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.submittedAfter = submittedAfter
            self.submittedBefore = submittedBefore
        }

        public func validate(name: String) throws {
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, max: 32)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, min: 1)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.validate(self.jobName, name: "jobName", parent: name, max: 64)
            try self.validate(self.jobName, name: "jobName", parent: name, min: 1)
            try self.validate(self.jobName, name: "jobName", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 500)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^\\p{ASCII}{0,8192}$")
        }

        private enum CodingKeys: String, CodingKey {
            case datastoreId = "DatastoreId"
            case jobName = "JobName"
            case jobStatus = "JobStatus"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case submittedAfter = "SubmittedAfter"
            case submittedBefore = "SubmittedBefore"
        }
    }

    public struct ListFHIRImportJobsResponse: AWSDecodableShape {
        ///  The properties of a listed FHIR import jobs, including the ID, ARN, name, and the status of the job.
        public let importJobPropertiesList: [ImportJobProperties]
        ///  A pagination token used to identify the next page of results to return for a ListFHIRImportJobs query.
        public let nextToken: String?

        public init(importJobPropertiesList: [ImportJobProperties], nextToken: String? = nil) {
            self.importJobPropertiesList = importJobPropertiesList
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case importJobPropertiesList = "ImportJobPropertiesList"
            case nextToken = "NextToken"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        ///  The Amazon Resource Name(ARN) of the Data Store for which tags are being added.
        public let resourceARN: String

        public init(resourceARN: String) {
            self.resourceARN = resourceARN
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, max: 1011)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, min: 1)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, pattern: "^arn:aws((-us-gov)|(-iso)|(-iso-b)|(-cn))?:healthlake:[a-z0-9-]+:\\d{12}:datastore\\/fhir\\/.{32}$")
        }

        private enum CodingKeys: String, CodingKey {
            case resourceARN = "ResourceARN"
        }
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        ///  Returns a list of tags associated with a Data Store.
        public let tags: [Tag]?

        public init(tags: [Tag]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct PreloadDataConfig: AWSEncodableShape & AWSDecodableShape {
        /// The type of preloaded data. Only Synthea preloaded data is supported.
        public let preloadDataType: PreloadDataType

        public init(preloadDataType: PreloadDataType) {
            self.preloadDataType = preloadDataType
        }

        private enum CodingKeys: String, CodingKey {
            case preloadDataType = "PreloadDataType"
        }
    }

    public struct S3Configuration: AWSEncodableShape & AWSDecodableShape {
        ///  The KMS key ID used to access the S3 bucket.
        public let kmsKeyId: String
        ///  The S3Uri is the user specified S3 location of the FHIR data to be imported into Amazon HealthLake.
        public let s3Uri: String

        public init(kmsKeyId: String, s3Uri: String) {
            self.kmsKeyId = kmsKeyId
            self.s3Uri = s3Uri
        }

        public func validate(name: String) throws {
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, max: 400)
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, min: 1)
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, pattern: "^(arn:aws((-us-gov)|(-iso)|(-iso-b)|(-cn))?:kms:)?([a-z]{2}-[a-z]+(-[a-z]+)?-\\d:)?(\\d{12}:)?(((key/)?[a-zA-Z0-9-_]+)|(alias/[a-zA-Z0-9:/_-]+))$")
            try self.validate(self.s3Uri, name: "s3Uri", parent: name, max: 1024)
            try self.validate(self.s3Uri, name: "s3Uri", parent: name, pattern: "^s3://[a-z0-9][\\.\\-a-z0-9]{1,61}[a-z0-9](/.*)?$")
        }

        private enum CodingKeys: String, CodingKey {
            case kmsKeyId = "KmsKeyId"
            case s3Uri = "S3Uri"
        }
    }

    public struct SseConfiguration: AWSEncodableShape & AWSDecodableShape {
        ///  The KMS encryption configuration used to provide details for data encryption.
        public let kmsEncryptionConfig: KmsEncryptionConfig

        public init(kmsEncryptionConfig: KmsEncryptionConfig) {
            self.kmsEncryptionConfig = kmsEncryptionConfig
        }

        public func validate(name: String) throws {
            try self.kmsEncryptionConfig.validate(name: "\(name).kmsEncryptionConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case kmsEncryptionConfig = "KmsEncryptionConfig"
        }
    }

    public struct StartFHIRExportJobRequest: AWSEncodableShape {
        /// An optional user provided token used for ensuring idempotency.
        public let clientToken: String
        /// The Amazon Resource Name used during the initiation of the job.
        public let dataAccessRoleArn: String
        /// The AWS generated ID for the Data Store from which files are being exported for an export job.
        public let datastoreId: String
        /// The user generated name for an export job.
        public let jobName: String?
        /// The output data configuration that was supplied when the export job was created.
        public let outputDataConfig: OutputDataConfig

        public init(clientToken: String = StartFHIRExportJobRequest.idempotencyToken(), dataAccessRoleArn: String, datastoreId: String, jobName: String? = nil, outputDataConfig: OutputDataConfig) {
            self.clientToken = clientToken
            self.dataAccessRoleArn = dataAccessRoleArn
            self.datastoreId = datastoreId
            self.jobName = jobName
            self.outputDataConfig = outputDataConfig
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.dataAccessRoleArn, name: "dataAccessRoleArn", parent: name, max: 2048)
            try self.validate(self.dataAccessRoleArn, name: "dataAccessRoleArn", parent: name, min: 20)
            try self.validate(self.dataAccessRoleArn, name: "dataAccessRoleArn", parent: name, pattern: "^arn:aws(-[^:]+)?:iam::[0-9]{12}:role/.+$")
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, max: 32)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, min: 1)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.validate(self.jobName, name: "jobName", parent: name, max: 64)
            try self.validate(self.jobName, name: "jobName", parent: name, min: 1)
            try self.validate(self.jobName, name: "jobName", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.outputDataConfig.validate(name: "\(name).outputDataConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case dataAccessRoleArn = "DataAccessRoleArn"
            case datastoreId = "DatastoreId"
            case jobName = "JobName"
            case outputDataConfig = "OutputDataConfig"
        }
    }

    public struct StartFHIRExportJobResponse: AWSDecodableShape {
        /// The AWS generated ID for the Data Store from which files are being exported for an export job.
        public let datastoreId: String?
        /// The AWS generated ID for an export job.
        public let jobId: String
        /// The status of a FHIR export job. Possible statuses are SUBMITTED, IN_PROGRESS, COMPLETED, or FAILED.
        public let jobStatus: JobStatus

        public init(datastoreId: String? = nil, jobId: String, jobStatus: JobStatus) {
            self.datastoreId = datastoreId
            self.jobId = jobId
            self.jobStatus = jobStatus
        }

        private enum CodingKeys: String, CodingKey {
            case datastoreId = "DatastoreId"
            case jobId = "JobId"
            case jobStatus = "JobStatus"
        }
    }

    public struct StartFHIRImportJobRequest: AWSEncodableShape {
        /// Optional user provided token used for ensuring idempotency.
        public let clientToken: String
        /// The Amazon Resource Name (ARN) that gives Amazon HealthLake access permission.
        public let dataAccessRoleArn: String
        /// The AWS-generated Data Store ID.
        public let datastoreId: String
        /// The input properties of the FHIR Import job in the StartFHIRImport job request.
        public let inputDataConfig: InputDataConfig
        /// The name of the FHIR Import job in the StartFHIRImport job request.
        public let jobName: String?
        public let jobOutputDataConfig: OutputDataConfig

        public init(clientToken: String = StartFHIRImportJobRequest.idempotencyToken(), dataAccessRoleArn: String, datastoreId: String, inputDataConfig: InputDataConfig, jobName: String? = nil, jobOutputDataConfig: OutputDataConfig) {
            self.clientToken = clientToken
            self.dataAccessRoleArn = dataAccessRoleArn
            self.datastoreId = datastoreId
            self.inputDataConfig = inputDataConfig
            self.jobName = jobName
            self.jobOutputDataConfig = jobOutputDataConfig
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.dataAccessRoleArn, name: "dataAccessRoleArn", parent: name, max: 2048)
            try self.validate(self.dataAccessRoleArn, name: "dataAccessRoleArn", parent: name, min: 20)
            try self.validate(self.dataAccessRoleArn, name: "dataAccessRoleArn", parent: name, pattern: "^arn:aws(-[^:]+)?:iam::[0-9]{12}:role/.+$")
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, max: 32)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, min: 1)
            try self.validate(self.datastoreId, name: "datastoreId", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.inputDataConfig.validate(name: "\(name).inputDataConfig")
            try self.validate(self.jobName, name: "jobName", parent: name, max: 64)
            try self.validate(self.jobName, name: "jobName", parent: name, min: 1)
            try self.validate(self.jobName, name: "jobName", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.jobOutputDataConfig.validate(name: "\(name).jobOutputDataConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case dataAccessRoleArn = "DataAccessRoleArn"
            case datastoreId = "DatastoreId"
            case inputDataConfig = "InputDataConfig"
            case jobName = "JobName"
            case jobOutputDataConfig = "JobOutputDataConfig"
        }
    }

    public struct StartFHIRImportJobResponse: AWSDecodableShape {
        /// The AWS-generated Data Store ID.
        public let datastoreId: String?
        /// The AWS-generated job ID.
        public let jobId: String
        /// The status of an import job.
        public let jobStatus: JobStatus

        public init(datastoreId: String? = nil, jobId: String, jobStatus: JobStatus) {
            self.datastoreId = datastoreId
            self.jobId = jobId
            self.jobStatus = jobStatus
        }

        private enum CodingKeys: String, CodingKey {
            case datastoreId = "DatastoreId"
            case jobId = "JobId"
            case jobStatus = "JobStatus"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        ///  The key portion of a tag. Tag keys are case sensitive.
        public let key: String
        ///  The value portion of tag. Tag values are case sensitive.
        public let value: String

        public init(key: String, value: String) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.key, name: "key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        ///  The Amazon Resource Name(ARN)that gives Amazon HealthLake access to the Data Store which tags are being added to.
        public let resourceARN: String
        ///  The user specified key and value pair tags being added to a Data Store.
        public let tags: [Tag]

        public init(resourceARN: String, tags: [Tag]) {
            self.resourceARN = resourceARN
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, max: 1011)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, min: 1)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, pattern: "^arn:aws((-us-gov)|(-iso)|(-iso-b)|(-cn))?:healthlake:[a-z0-9-]+:\\d{12}:datastore\\/fhir\\/.{32}$")
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceARN = "ResourceARN"
            case tags = "Tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        ///  "The Amazon Resource Name(ARN) of the Data Store for which tags are being removed
        public let resourceARN: String
        ///  The keys for the tags to be removed from the Healthlake Data Store.
        public let tagKeys: [String]

        public init(resourceARN: String, tagKeys: [String]) {
            self.resourceARN = resourceARN
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, max: 1011)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, min: 1)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, pattern: "^arn:aws((-us-gov)|(-iso)|(-iso-b)|(-cn))?:healthlake:[a-z0-9-]+:\\d{12}:datastore\\/fhir\\/.{32}$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceARN = "ResourceARN"
            case tagKeys = "TagKeys"
        }
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct InputDataConfig: AWSEncodableShape & AWSDecodableShape {
        /// The S3Uri is the user specified S3 location of the FHIR data to be imported into Amazon HealthLake.
        public let s3Uri: String?

        public init(s3Uri: String? = nil) {
            self.s3Uri = s3Uri
        }

        public func validate(name: String) throws {
            try self.validate(self.s3Uri, name: "s3Uri", parent: name, max: 1024)
            try self.validate(self.s3Uri, name: "s3Uri", parent: name, pattern: "^s3://[a-z0-9][\\.\\-a-z0-9]{1,61}[a-z0-9](/.*)?$")
        }

        private enum CodingKeys: String, CodingKey {
            case s3Uri = "S3Uri"
        }
    }

    public struct OutputDataConfig: AWSEncodableShape & AWSDecodableShape {
        ///  The output data configuration that was supplied when the export job was created.
        public let s3Configuration: S3Configuration?

        public init(s3Configuration: S3Configuration? = nil) {
            self.s3Configuration = s3Configuration
        }

        public func validate(name: String) throws {
            try self.s3Configuration?.validate(name: "\(name).s3Configuration")
        }

        private enum CodingKeys: String, CodingKey {
            case s3Configuration = "S3Configuration"
        }
    }
}

// MARK: - Errors

/// Error enum for HealthLake
public struct HealthLakeErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize HealthLake
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// Access is denied. Your account is not authorized to perform this operation.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// The Data Store is in a transition state and the user requested action can not be performed.
    public static var conflictException: Self { .init(.conflictException) }
    /// Unknown error occurs in the service.
    public static var internalServerException: Self { .init(.internalServerException) }
    ///  The requested Data Store was not found.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// The user has exceeded their maximum number of allowed calls to the given API.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The user input parameter was invalid.
    public static var validationException: Self { .init(.validationException) }
}

extension HealthLakeErrorType: Equatable {
    public static func == (lhs: HealthLakeErrorType, rhs: HealthLakeErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension HealthLakeErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
